package cn.iocoder.yudao.module.security.service.rule;

import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.iocoder.yudao.module.security.controller.admin.rule.vo.*;
import cn.iocoder.yudao.module.security.dal.dataobject.rule.SecurityRuleDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.security.dal.mysql.rule.SecurityRuleMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.security.enums.ErrorCodeConstants.*;

/**
 * 规则 Service 实现类
 *
 * @author 超管
 */
@Service
@Validated
public class SecurityRuleServiceImpl implements SecurityRuleService {

    @Resource
    private SecurityRuleMapper ruleMapper;

    @Override
    public Long createRule(SecurityRuleSaveReqVO createReqVO) {
        // 插入
        SecurityRuleDO rule = BeanUtils.toBean(createReqVO, SecurityRuleDO.class);
        ruleMapper.insert(rule);
        // 返回
        return rule.getId();
    }

    @Override
    public void updateRule(SecurityRuleSaveReqVO updateReqVO) {
        // 校验存在
        validateRuleExists(updateReqVO.getId());
        // 更新
        SecurityRuleDO updateObj = BeanUtils.toBean(updateReqVO, SecurityRuleDO.class);
        ruleMapper.updateById(updateObj);
    }

    @Override
    public void deleteRule(Long id) {
        // 校验存在
        validateRuleExists(id);
        // 删除
        ruleMapper.deleteById(id);
    }

    private void validateRuleExists(Long id) {
        if (ruleMapper.selectById(id) == null) {
            throw exception(RULE_NOT_EXISTS);
        }
    }

    @Override
    public SecurityRuleDO getRule(Long id) {
        return ruleMapper.selectById(id);
    }

    @Override
    public PageResult<SecurityRuleDO> getRulePage(SecurityRulePageReqVO pageReqVO) {
        return ruleMapper.selectPage(pageReqVO);
    }

    @Override
    public Boolean importRuleList(List<String> lines, Boolean updateSupport) {
        Pattern msgPattern = Pattern.compile("msg:\\s*\"([^\"]*)\"");
        Pattern sidPattern = Pattern.compile("sid:\\s*(\\d+)");
        Pattern gidPattern = Pattern.compile("gid:\\s*(\\d+)");
        for (String line : lines) {
            if (StringUtils.isBlank(line)) {
                continue;
            }
            if (line.startsWith("#")) {
                continue;
            }
            if (selectByContent(line) != null) {
                continue;
            }
            String msg = extractValue(msgPattern, line);
            String sid = extractValue(sidPattern, line);
            String gid = extractValue(gidPattern, line);
            if (StringUtils.isBlank(gid)) {
                gid = "1";
            }
            SecurityRuleDO rule = SecurityRuleDO.builder().content(line).msg(msg).sId(sid).gId(gid).build();
            rule.setStatus(CommonStatusEnum.ENABLE.getStatus());
            ruleMapper.insert(rule);
        }
        return true;
    }

    SecurityRuleDO selectByContent(String content) {
        return ruleMapper.selectOne(new LambdaQueryWrapperX<SecurityRuleDO>().eq(SecurityRuleDO::getContent, content));
    }

    private static String extractValue(Pattern pattern, String line) {
        Matcher matcher = pattern.matcher(line);
        return matcher.find() ? matcher.group(1) : null;
    }


}